﻿using System;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using NUnit.Framework.SyntaxHelpers;
using Yaml.Presentation.Parsing;
using Yaml.Presentation.Tokens;

namespace Yaml.Tests.Presentation.ScannerTests {
    [TestFixture]
    public class Directive {
        [Test]
        public void Yaml1_1() {
            Scanner s = Helper.CreateScanner("%YAML 1.1");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.1' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={9:0,9} end={9:0,9}>"));
        }
        [Test]
        public void Yaml1_2() {
            Scanner s = Helper.CreateScanner("%YAML 1.2");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.2' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={9:0,9} end={9:0,9}>"));
        }
        [Test, ExpectedException(typeof(Yaml.Presentation.ScannerException))]
        public void Yaml2_0() {
            Scanner s = Helper.CreateScanner("%YAML 2.0");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
        }

        [Test]
        public void PrimaryTagHandle() {
            Scanner s = Helper.CreateScanner("%TAG ! tag:ben-kiki.org,2000:app/");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!' prefix='tag:ben-kiki.org,2000:app/' start={0:0,0} end={33:0,33}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={33:0,33} end={33:0,33}>"));
        }

        [Test]
        public void SecondaryTagHandle() {
            Scanner s = Helper.CreateScanner("%TAG !! tag:yaml.org,2002:");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!!' prefix='tag:yaml.org,2002:' start={0:0,0} end={26:0,26}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={26:0,26} end={26:0,26}>"));
        }

        [Test]
        public void NamedTagHandle() {
            Scanner s = Helper.CreateScanner("%TAG !o! tag:ben-kiki.org,2000:");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!o!' prefix='tag:ben-kiki.org,2000:' start={0:0,0} end={31:0,31}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={31:0,31} end={31:0,31}>"));
        }

        [Test]
        public void LocalTagPrefix() {
            Scanner s = Helper.CreateScanner("%TAG !o! !foo");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!o!' prefix='!foo' start={0:0,0} end={13:0,13}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={13:0,13} end={13:0,13}>"));
        }

        [Test]
        public void MultipleDirectives() {
            Scanner s = Helper.CreateScanner("%YAML 1.1\n%TAG !o! !foo\r\n%TAG ! tag:ben-kiki.org,2000:app/");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.1' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!o!' prefix='!foo' start={10:1,0} end={23:1,13}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<TagDirectiveToken handle='!' prefix='tag:ben-kiki.org,2000:app/' start={25:2,0} end={58:2,33}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={58:2,33} end={58:2,33}>"));
        }
    }
}

